/**
*\file main.c
*\author H4201
*/

/*MODULES USED*/
#include <unistd.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <pthread.h>

#include "main.h"
#include "../../rt_ciai/interface/partage_simu.h"
#include "traitement.h"

/*DEFINITIONS AND MACROS*/
#define RETOUR_MAUVAIS_NOMBRE_ARGUMENTS 2
#define NB_ARG_ATTENDUS 4

/*PROTOTYPES OF LOCAL FUNCTIONS*/
void init_main();

/*GLOBAL VARIABLES*/
/**
	descripteur du thread d'envoi des pieces
*/
pthread_t thread_traitement;

void affiche_aide() {	
	printf("aguments attendus: dimensionsA, dimensionsB, cadence, pourcentage de rebut\n");
	printf("commandes: stop, imp, film, carton, palette, rebut, arret urgence, prodA, prodB, pid\n");
}

/**
	* programme principal.
	* lance le thread d'envoi de pièces et attend les messages de l'utilisateur.
	*\param argc taille du tableau argv
	*\param argv liste d'arguments donnés au lancement du programme
*/
int main (int argc, char * argv[] )
{
	//protection
	if (argc < NB_ARG_ATTENDUS) {
		affiche_aide();
		return RETOUR_MAUVAIS_NOMBRE_ARGUMENTS;
	}

	//init
	init_main(atoi(argv[1]), atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));

	//moteur
	char ret[100];
	while (!arret_demande) {
		scanf("%s", ret);
		if (!strcmp(ret, "stop")) {
			arret_demande = !arret_demande;
		} else if (!strcmp(ret, "clapet")) {
			g_shm->clapet = !g_shm->clapet;
			(g_shm->clapet == OK) ? printf("clapet ouvert\n") : printf("clapet fermé\n");			
		} else if (!strcmp(ret, "imp")) {
			g_shm->imp = !g_shm->imp;
			(g_shm->imp == OK) ? printf("imprimante OK\n") : printf("imprimante NOT OK\n");
		} else if (!strcmp(ret, "film")) {
			g_shm->film = !g_shm->film;
			(g_shm->film == OK) ? printf("filmeuse OK\n") : printf("filmeuse NOT OK\n");
		} else if (!strcmp(ret, "carton")) {
			g_shm->carton = !g_shm->carton;
			(g_shm->carton == OK) ? printf("carton OK\n") : printf("carton NOT OK\n");
		} else if (!strcmp(ret, "palette")) {
			g_shm->palette = !g_shm->palette;
			(g_shm->palette == OK) ? printf("palette OK\n") : printf("palette NOT OK\n");
		} else if (!strcmp(ret, "rebut")) {
			pthread_mutex_lock(&mtx_rebut_oblige);
			rebut_oblige++;
			pthread_mutex_unlock(&mtx_rebut_oblige);
		} else if (!strcmp(ret, "au")) {
			kill(pid_application, SIGUSR2); 
		} else if (!strcmp(ret, "prodA")) {
			produit_courant = 0;
			printf("envoi de produit A\n");
		} else if (!strcmp(ret, "prodB")) {
			produit_courant = 1;
			printf("envoi de produit B\n");
		// Récupérer le PID de notre appli, pour lui envoyer des signaux
		} else if (!strcmp(ret, "pid")) {
			pid_application = g_shm->pid_appli;
			printf("pid mis à jour\n");
		} else if(!strcmp(ret, "aide") || !strcmp(ret, "help")) {
			affiche_aide();
		}
	}

	//fin
	pthread_join(thread_traitement, NULL);
	
	return 0;
}

/**
	* initialise les variables globales, se connecte à la shm, lance le thread d'envoi de pièces
*/
void init_main(int dim_A, int dim_B, int cadence, int p_rebut) {
	dimensions[0] = dim_A;
	dimensions[1] = dim_B;
	cadence_piece = cadence;
	pourcentage_rebut = p_rebut;
	
	pthread_mutex_t mtx_rebut_oblige = PTHREAD_MUTEX_INITIALIZER;

	// Création et attachement de la mémoire partagée
	int shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
	if (shm_fd == -1) {
		perror("Erreur shm_open");
		exit(1);
	}

	if (ftruncate(shm_fd, sizeof(shm_data)) == -1) {
		perror("Erreur ftruncate");
		exit(1);
	}

	g_shm = mmap(NULL, sizeof(shm_data), PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
	if (g_shm == MAP_FAILED) {
		perror("Erreur mmap");
		exit(1);
	}

	g_shm->clapet = NOK;
	g_shm->dim = OK;
	g_shm->imp = OK;
	g_shm->film = OK;
	g_shm->carton = OK;
	g_shm->palette = OK;

	pid_application = 0;

	pthread_create (&thread_traitement, NULL , traitement , NULL); 
	arret_demande = 0;
}


